// 注册服务：业务逻辑
package service

import (
	"errors"
	"im-v1/config"
	"im-v1/database"
	"im-v1/model"
	"im-v1/tool"
	"log"
	"time"
)

var (
	durationForAuthInRedis = 15 * time.Minute // 邮箱注册码 auth_code 在 redis保存时间 -> 15 min
	durationForToken       = 5 * time.Hour    // token 保存时间 -> 5 hour
)

// 检查是否已经注册过，true已经注册，false未注册
func IsAlreadyRegister(mailbox string) bool {
	raw, _ := model.FindByMailbox(mailbox)
	return raw != 0 // 不为零，代表被注册 -> true
}

// 邮箱注册验证码
func GetAuthCode(toMailbox string) string {

	// 检查是否已经注册
	if IsAlreadyRegister(toMailbox) {
		return "already register"
	}

	// 发送邮件
	randWord := tool.RandString(6)
	err := tool.SendMail(
		&config.Tconf.MailConfig,
		[]string{toMailbox},
		"goim-v1 注册验证码",
		randWord,
	)
	if err != nil {
		log.Println("[regist_usr_service GetAuthCode] ", err)
		return "failed send mail"
	}

	// 记录到redis，15分钟过期
	database.Redis.Set(config.RegisterCode+toMailbox, randWord, durationForAuthInRedis)

	return "success"
}

// 是否已经注册 -> 注册验证 -> 创建账号
func Register(usr *model.Usr, code string) (string, error) {

	// 检查是否已经注册
	if IsAlreadyRegister(usr.Mailbox) {
		return "", errors.New("already register")
	}

	// 检查验证码正确性
	realCode := database.Redis.Get(config.RegisterCode + usr.Mailbox).Val()
	if realCode != code {
		return "", errors.New("verification code error")
	}

	// 新建用户并返回token
	usr.Status = 1 // 已经注册状态
	model.NewUsr(usr)
	database.Redis.Del(config.RegisterCode + usr.Mailbox) // 删除redis-key

	// 生成token
	token, err := tool.GenerateToken(usr.Id, usr.Mailbox, usr.Nickname, durationForToken)
	if err != nil {
		log.Printf("[regist_usr_service Register] %v", err)
		return "", errors.New("token code create failed")
	}
	// 返回token
	return token, nil
}

// 登录核心逻辑：
// 已经注册 -> 密码正确 -> 生成token -> 返回个人信息
func Login(mailbox, password string) (string, *model.UsrOds, error) {

	// 查找个人信息
	num, usr := model.FindByMailbox(mailbox)

	// 加密后判断
	if num == 0 || usr != nil && usr.Password != tool.EncryptMD5(password) {
		return "", nil, errors.New("账号不存在 或者 密码错误")
	}

	// 生成token
	token, err := tool.GenerateToken(usr.Id, usr.Mailbox, usr.Nickname, durationForToken)
	if err != nil {
		log.Printf("[regist_usr_service Login] %v", err)
		return "", nil, errors.New("token code create failed")
	}
	// 返回token
	return token, usr.TransformOds(), nil
}
